
package tankattack.sprites;

import gamepack.*;
import java.awt.event.KeyEvent;
import java.util.Vector;

import java.awt.*;

/** @author Somanath
	@version 1.1
*/

// Possible values for 'type','curFrame' & 'state' attribute.
interface ETankType  { int TYPE1=0, TYPE2=1; }
interface ETankFrame { int LEFT=0,RIGHT=1,UP=2,DOWN=3,BORN1=4, BORN2=5; }
interface ETankState extends SpriteState { int CREATION=1;  }

/**  CompileTime class Dependency - Bullet
 *   Runtime class Dependency     - Tank | Brick
 *   RunTime interface Requirements -
 *        "tankattack.sprites.Tank","COLLIDABLE_BRICK","P1_BULLET","P2_BULLET"
 *   Exported Attributes: "ENEMY_BULLET"
*/
public class EnemyTank extends Sprite implements ETankType,ETankFrame,ETankState {

    public static Resource r = ResourceLoader.getResource("tankattack.sprites.EnemyTank");
	
	static {
	   //System.out.println("#########################  EnemyTank.java Compiled ##########################");
	   }



	public static String bulletSpawnStr = r.getValue("bulletSpawnStr"); // expecting it to have placeholders for x,y,dir
	public static String explosionSpawnStr = r.getValue("explosionSpawnStr"); // expecting it to have placeholders for x,y
	
	public static int speedOfTank1 = r.getValueAsInt("speedOfTank1");
	public static int healthOfTank1 = r.getValueAsInt("healthOfTank1");	
	public static int speedOfTank2 = r.getValueAsInt("speedOfTank2");
	public static int healthOfTank2 = r.getValueAsInt("healthOfTank2"); 
	
	//--------------------------------------------------------------------
	int speed;
	boolean moving = false;
	int newDirection = Direction.SOUTH;
    public MotionController mc;              // 4way Top view Motion controller
    public Joypad j;                         // Use this to move EnemyTank
	TimeStamp creationTime = new TimeStamp(2000);
	TimeStamp bulletSpawnTime = new TimeStamp(4000);
	//--------------------------------------------------------------------

	//<Data name="spawnformat"> x=%d:0,y=%d:0,type=%d:0:(0-WEAK 1-STRONG) </Data>
	public EnemyTank() { // Mandatory - x,y,type
		res = r;
		setAttribute( "BLOCK", "HURTABLE" );
        blockers = Environment.getAttributes("BLOCK");
		if( type == TYPE2 ) {// TYPE2 is
			speed = speedOfTank2; //6;       // Faster and
			health = healthOfTank2; //300;    // Stronger
		}
		else {
			speed = speedOfTank1; //3;
			health = healthOfTank1; //100;
		}
		curFrame = BORN1;
		mc = new TopViewMotionController(this,speed);
        j = new Joypad( new boolean[Joypad.MIN_BUTTONS] );
		startSprite(CREATION);
	}

    public boolean notify(int name,int ... value) {
        switch( name ) {
            case JoypadEvent.DIRECTION_CHANGE : curFrame = dir; //value[0]; break;
            //case JoypadEvent.MOVEMENT: curFrame ++; if ( curFrame > len ) curFrame =0;
        }
        return true;
    }

    public void handleCollision(Sprite bullet,Sprite prey) {
        if( !bullet.valid() || !prey.valid()) return;
        String s = prey.getShortName();

		String thisClassName = getShortName();  // To avoid hardcoding. 
        if( s.equals(thisClassName) ) { // If prey is mykind don't bother  
			return;
        }
        if ( bullet.getShortName().equals( s ) && prey.parent != null) {    // hmm bullet vs bullet collision
			if ( prey.parent.getShortName().equals(thisClassName) )  {  // If prey's parent is my Kind, Gosh, my own blood, ahem my own bullets.
				return;                                                 // so don't kill my kind's bullet. 
			}
		}
		// Hurt everyone else. (Have already taken care of collision with mykind. mykind's bullet. 
          bullet.setState( Sprite.DYING );
          prey.hurt( 100 ); // Strong brick won't get killed.
		
			// If HURTABLE_P and HURTABLE_E are set sensibly 
			//then the bullet can never collide with EnemyTanks/EnemyBullets.
     }

	public void run() {
		if( state == NORMAL ) {
			normal();
		} else if ( state == CREATION ) {
			creation();
		} else if ( state == DYING) { 
			Sprite.spawn( String.format(explosionSpawnStr,x,y), this ); 
			setState(DEAD); 
		} else if ( state == DEAD ) {
			stopSprite();
		}
	
	
	/*	switch( state) {
			case CREATION:	creation();		break;
			case NORMAL:	normal();	 	break;
			case DYING:		Sprite.spawn( String.format(explosionSpawnStr,x,y), this ); setState(DEAD); break;								
			case DEAD:      stopSprite();   break;
		} */
	}

	public void creation() {
        if( firstTime ) {
   		    curFrame = BORN1;
		    creationTime.reset();
            firstTime = false;
        }
		if( creationTime.elapsed() ) { setState(NORMAL); }
		curFrame = (curFrame==BORN1)? BORN2: BORN1;
	}

	public void normal() {

       if( firstTime ) {
	  	  curFrame = dir = Direction.SOUTH; // curFrame and dir are in sync
          bulletSpawnTime.reset();
          firstTime = false;
          j.clear();
	   }
		if( ! moving ) {
			newDirection = randomDirection();
			j.setDirection( newDirection, true );
			//if( Motion.canTurn( this, newDirection , newDirection ) ) { // frame is same as direction
			//    Motion.turn( this, newDirection , newDirection );
				moving = true;
			//}
		} else {
			if( !mc.move(j) ) {
				moving = false;
			}
			if( bulletSpawnTime.elapsed() ) {
               fireBullet();
            }
		}
	}

	static int randomDirection() {
		return (int) ( Math.random()*3 + 0.5); // range [0,1,2,3]
	}

	public void fireBullet() {
		Rectangle r = res.img[type][curFrame].getBounds();
		int gap = 5,speed = this.speed + 2;
		if ( curFrame == LEFT ) {
			Sprite.spawn( String.format(bulletSpawnStr,x+r.x-gap,y,WEST), this );
		} else if ( curFrame == RIGHT ) {
			Sprite.spawn( String.format(bulletSpawnStr,x+r.x+r.width+gap,y,EAST), this );
		} else if ( curFrame == UP ) {
			Sprite.spawn( String.format(bulletSpawnStr,x   ,y+r.y-gap,NORTH), this );
		} else if ( curFrame == DOWN ) {
			Sprite.spawn( String.format(bulletSpawnStr,x ,y+r.y+r.height+gap,SOUTH), this );
		}
		
		/*switch(curFrame) {
			case LEFT:	Sprite.spawn( String.format(bulletSpawnStr,x+r.x-gap,y,WEST), this );			break;
			case RIGHT:	Sprite.spawn( String.format(bulletSpawnStr,x+r.x+r.width+gap,y,EAST), this );	break;			
			case UP:	Sprite.spawn( String.format(bulletSpawnStr,x   ,y+r.y-gap,NORTH), this );		break;
			case DOWN:	Sprite.spawn( String.format(bulletSpawnStr,x ,y+r.y+r.height+gap,SOUTH), this );	break;			
		}*/
	}

/*    public static Vector[] getBulletColliders() {
       return Environment.getAttributes("COLLIDABLE_BRICK", "P1_BULLET", "P2_BULLET","tankattack.sprites.Tank" );
    }*/
}